package cn.xtits.xtf.common.db.sequence;

import cn.xtits.xtf.common.db.sequence.dao.SequenceDao;
import org.apache.commons.lang3.StringUtils;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created by ShengHaiJiang on 16/4/15.
 */
public class DefaultSequence implements Sequence {

    private final Lock lock = new ReentrantLock();

    private SequenceDao sequenceDao;

    private String sequenceName;

    private volatile SequenceRange currentSequenceRange;

    @Override
    public long nextValue(String sequenceName) throws SequenceException {

        if (StringUtils.isNotEmpty(sequenceName)) this.sequenceName = sequenceName;

        if (currentSequenceRange == null) {
            lock.lock();
            try {
                if (currentSequenceRange == null) {
                    currentSequenceRange = sequenceDao.nextRange(sequenceName);
                }
            } finally {
                lock.unlock();
            }
        }
        long value = currentSequenceRange.getAndIncrement();
        if (value == -1) {
            lock.lock();
            try {
                for (;;) {
                    if (currentSequenceRange.isOver()) {
                        currentSequenceRange = sequenceDao.nextRange(sequenceName);
                    }

                    value = currentSequenceRange.getAndIncrement();

                    if (value == -1) continue;

                    break;
                }
            } finally {
                lock.unlock();
            }
        }

        return value;
    }
}
